import { isObject } from "../util/index";
function isReservedTag(tag) {
  return [
    "div",
    "p",
    "span",
    "h1",
    "h2",
    "h3",
    "h4",
    "h5",
    "input",
    "select",
    "text",
  ].includes(tag);
}
export function createElement(vm, tag, data = {}, ...children) {
  let key = data.key;
  if (key) {
    delete data.key;
  }
  // 如果是原始标签
  if (isReservedTag(tag)) {
    // 返回vnode
    return vnode(tag, data, key, children, undefined);
  } else {
    // 非原始标签，说明是组件
    let Ctor = vm.$options.components[tag]; //子组件的构造函数
    return createComponent(vm, tag, data, key, children, Ctor);
  }
}
// 创建组件的虚拟dom
function createComponent(vm, tag, data, key, children, Ctor) {
  if (isObject(Ctor)) {
    Ctor = vm.$options._base.extend(Ctor);
  }
  data.hook = {
    init(vnode) {
      let child = (vnode.componentInstance = new Ctor({ _isComponent: true }));
      // 子组件 触发生命周期钩子
      child.$mount();
    }
  };
  return vnode(`vue-component-${Ctor.cid}-${tag}`, data, key, undefined, {
    Ctor,
    children,
  });
}

export function createTextNode(vm, text) {
  return vnode(undefined, undefined, undefined, undefined, text, undefined);
}

function vnode(tag, data, key, children, text, componentOptions) {
  // 生成虚拟节点，通过_c _v创建对象，描述虚拟dom的操作
  return {
    tag,
    data,
    key,
    children,
    text,
    componentOptions,
  };
}
// 生成虚拟dom的流程
// 1：将template转成ast语法树 -> 生成render -> 生成虚拟dom -> 真实dom
// 2：重新生成虚拟dom，-> 更新dom
